#region License and Copyright

/*
 * Copyright (C) 2008 Nathan Palmer
 * http://www.nathanpalmer.com
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Author:
 *     Nathan Palmer <nathan1@nathanpalmer.com>
 */

#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Amazon.S3;
using System.IO;

namespace AmazonS3Explorer
{
    public partial class Interface : Form
    {
        S3Service s3;
        string accessKeyId, secretKey;
        private int? lastTreeSelection;

        public Interface()
        {
            InitializeComponent();

            lastTreeSelection = null;

            accessKeyId = "1E4XR6BT3MK36P7KSM82";
            secretKey = "oQM2z7O8Ws7T/TEF41pReALU/jZxjT/G+f0VbzoU";

            s3 = new S3Service(accessKeyId, secretKey);
        }

        private void Interface_Load(object sender, EventArgs e)
        {
            RefreshTree();
        }

        private void RefreshTree()
        {
            TreeNode rootNode = treeView1.Nodes.Add("/");            

            foreach (S3Bucket bucket in s3.Buckets)
            {
                rootNode.Nodes.Add(bucket.Name, bucket.Name, 0);
            }

            rootNode.Expand();
        }

        private void RefreshBucketContents(string BucketName)
        {
            listView1.Items.Clear();

            S3Bucket bucket = s3.Buckets[BucketName];

            if (bucket != null)
            {
                foreach (S3Key key in bucket.Keys)
                {
                    ListViewItem listItem = new ListViewItem(key.Name);
                    listItem.ImageIndex = 2;
                    listItem.SubItems.Add(FileHelper.ToByteString(key.Size));
                    listItem.SubItems.Add(key.LastModified.ToShortDateString());
                    listView1.Items.Add(listItem);
                }
            }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            toolStripStatusLabel1.Text = e.Node.Name;            
            RefreshBucketContents(e.Node.Name);
        }

        private void treeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            //if (lastTreeSelection != null)
            //{
            //    TreeNode lastNode = treeView1.Nodes[(int)lastTreeSelection];
            //    if (lastNode != null)
            //        lastNode.ImageIndex = 0;
            //}

            //e.Node.ImageIndex = 1;
            //treeView1.Refresh();

            //lastTreeSelection = e.Node.Index;
        }

        private void listView1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (listView1.SelectedItems.Count != 1)
                {
                    deleteToolStripMenuItem.Visible = false;
                    //addToolStripMenuItem.Visible = true; 
                }
                //else
                //{
                //    deleteToolStripMenuItem.Visible = false;
                //    addToolStripMenuItem.Visible = true;
                //}

                contextMenuStrip1.Show(MousePosition);
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            S3Bucket bucket = s3.Buckets[treeView1.SelectedNode.Name];
            if (bucket != null)
            {
                if (bucket.Keys.Delete(listView1.SelectedItems[0].Text))
                {
                    RefreshBucketContents(bucket.Name);
                }
                else
                {
                    MessageBox.Show("There was a problem deleting the key");
                }
            }
            else
            {
                MessageBox.Show("There was a problem locating the bucket");
            }
        }

        private void addToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();

            if (openFileDialog1.FileName != "")
            {
                FileInfo file = new FileInfo(openFileDialog1.FileName);
                if (file.Exists)
                {
                    S3Bucket bucket = s3.Buckets[treeView1.SelectedNode.Name];
                    if (bucket != null)
                    {
                        S3Key key = bucket.Keys.Add(file.DirectoryName, file.Name);
                        RefreshBucketContents(bucket.Name);
                    }
                }
            }
        }

        private void listView1_DragDrop(object sender, DragEventArgs e)
        {
            S3Bucket bucket = s3.Buckets[treeView1.SelectedNode.Name];
            if (bucket != null)
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                foreach (string file in files)
                {
                    FileInfo fileObject = new FileInfo(file);

                    toolStripStatusLabel1.Text = "Adding " + fileObject.Name;

                    S3Key key = bucket.Keys.Add(fileObject.DirectoryName, fileObject.Name);
                }                    
            }

            RefreshBucketContents(bucket.Name);
        }

        private void listView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
            {
                e.Effect = DragDropEffects.All;
            }
        }

        private void listView1_DragLeave(object sender, EventArgs e)
        {
            
        }

        private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {                
                string[] files = new string[listView1.SelectedItems.Count];

                DragDropData ddd = new DragDropData();
                ddd.BucketName = treeView1.SelectedNode.Name;
                ddd.KeyNames = new string[listView1.SelectedItems.Count];

                for (int i = 0; i < listView1.SelectedItems.Count; i++)
                {
                    ddd.KeyNames[i] = listView1.SelectedItems[i].Text;
                    //S3Key key = bucket.Keys[listView1.SelectedItems[i].Text];
                    //string destinationFile = Path.Combine(tempPath, key.Name);
                    //if (File.Exists(destinationFile))
                    //    File.Delete(destinationFile);

                    //key.Save(tempPath);

                    //files[i] = destinationFile;
                }

                //DoDragDrop(new DataObject(DataFormats.FileDrop, files), DragDropEffects.Copy);

                S3Bucket bucket = s3.Buckets[ddd.BucketName];
                string tempPath = Path.GetTempPath();

                files = new string[ddd.KeyNames.Length];
                MyData.Extensions.DataObjectEx.SelectedItem[] SelectedItems = new MyData.Extensions.DataObjectEx.SelectedItem[ddd.KeyNames.Length];

                for (int i = 0; i < ddd.KeyNames.Length; i++)
                {
                    S3Key key = bucket.Keys[ddd.KeyNames[i]];
                    string destinationFile = Path.Combine(tempPath, key.Name);
                    if (File.Exists(destinationFile))
                        File.Delete(destinationFile);

                    SelectedItems[i].FileName = key.Name;
                    SelectedItems[i].WriteTime = new DateTime(2008, 1, 1);
                    SelectedItems[i].FileSize = key.Size;
                    SelectedItems[i].S3Service = s3;
                    SelectedItems[i].BucketName = bucket.Name;

                    //bgDragDrog.ReportProgress(0, "Downloading file " + key.Name);
                    //key.Save(tempPath);
                    //bgDragDrog.ReportProgress(0, "Download Complete for " + key.Name);

                    files[i] = destinationFile;
                }

                //DragDropLib.DataObject dd = new DragDropLib.DataObject();
                MyData.Extensions.DataObjectEx dataObject = new MyData.Extensions.DataObjectEx(SelectedItems);
                dataObject.SetData(MyData.Extensions.NativeMethods.CFSTR_FILEDESCRIPTORW, null);
                dataObject.SetData(MyData.Extensions.NativeMethods.CFSTR_FILECONTENTS, null);
                dataObject.SetData(MyData.Extensions.NativeMethods.CFSTR_PERFORMEDDROPEFFECT, null);
                dataObject.SetData(MyData.Extensions.NativeMethods.CFSTR_INDRAGLOOP, null);

                //DoDragDrop(new DataObject(DataFormats.FileDrop, files), DragDropEffects.Copy);
                DoDragDrop(dataObject, DragDropEffects.Copy);
                //DoDragDrop(new DragDropLib.DataObject(), DragDropEffects.Copy);
                //DoDragDrop(new DataObject(new DragDropLib.DataObject()), DragDropEffects.Copy);
            }
        }

        private void bgDragDrog_DoWork(object sender, DoWorkEventArgs e)
        {
            //DragDropData ddd = (DragDropData)e.Argument;

            //S3Bucket bucket = s3.Buckets[ddd.BucketName];
            //string tempPath = Path.GetTempPath();

            //string[] files = new string[ddd.KeyNames.Length];
            //MyData.Extensions.DataObjectEx.SelectedItem[] SelectedItems = new MyData.Extensions.DataObjectEx.SelectedItem[ddd.KeyNames.Length];

            //for (int i = 0; i < ddd.KeyNames.Length; i++)
            //{
            //    S3Key key = bucket.Keys[ddd.KeyNames[i]];
            //    string destinationFile = Path.Combine(tempPath, key.Name);
            //    if (File.Exists(destinationFile))
            //        File.Delete(destinationFile);

            //    bgDragDrog.ReportProgress(0, "Downloading file " + key.Name);
            //    key.Save(tempPath);
            //    bgDragDrog.ReportProgress(0, "Download Complete for " + key.Name);

            //    files[i] = destinationFile;
            //}

            //MyData.Extensions.DataObjectEx.SelectedItem[] SelectedItems = new DataObjectEx.SelectedItem[NumItems];
            //for (Int32 ItemCount = 0; ItemCount < SelectedItems.Length; ItemCount++)
            //{
            //}

            ////DoDragDrop(new DataObject(DataFormats.FileDrop, files), DragDropEffects.Copy);
            //DoDragDrop(new MyData.Extensions.DataObjectEx(
        }

        private void bgDragDrog_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            string userState = (string)e.UserState;
            toolStripStatusLabel1.Text = userState;
        }
    }

    public class DragDropData
    {
        public string BucketName;
        public string[] KeyNames;

    }
}